<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use Prettus\Validator\Contracts\ValidatorInterface;
use Prettus\Validator\Exceptions\ValidatorException;
use App\Http\Requests\DormRatingMainCreateRequest;
use App\Http\Requests\DormRatingMainUpdateRequest;
use App\Repositories\DormRatingMainRepository;
use App\Validators\DormRatingMainValidator;
use App\Models\Period;
use App\Models\Building;
use App\Models\DormitoryRating;
use App\Presenters\DormRatingMainPresenter;
use App\Models\RatingCategory;
use App\Models\RatingSubitem;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\DormitoryScoreExport;

/**
 * Class DormRatingMainsController.
 *
 * @package namespace App\Http\Controllers;
 */
class DormRatingMainsController extends Controller
{
    /**
     * @var DormRatingMainRepository
     */
    protected $repository;

    /**
     * @var DormRatingMainValidator
     */
    protected $validator;

    /**
     * DormRatingMainsController constructor.
     *
     * @param DormRatingMainRepository $repository
     * @param DormRatingMainValidator $validator
     */
    public function __construct(DormRatingMainRepository $repository, DormRatingMainValidator $validator)
    {
        $this->repository = $repository;
        $this->validator  = $validator;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $this->repository->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));
        $this->repository->setPresenter(DormRatingMainPresenter::class);
        if (\request()->has('export')) {
            $dormRatingMains = $this->repository->all();
        } else {
            $dormRatingMains = $this->repository->with('company')->paginate(\request()->get('limit', 20));
        }
        if (request()->wantsJson()) {

            return response()->json([
                'data' => $dormRatingMains,
            ]);
        }
        $periods = Period::orderBy('name', 'desc')->limit(24)->pluck('name', 'id');
        $buildings = Building::orderBy('name', 'asc')->pluck('name', 'id');
        return view('dormRatingMains.index', compact('dormRatingMains', 'periods', 'buildings'));
    }

    public function create()
    {
        $periods = Period::orderBy('name', 'desc')->limit(24)->pluck('name', 'id');
        $buildings = Building::orderBy('name', 'asc')->pluck('name', 'id');
        $ratingCategories = RatingCategory::with('ratingSubitems')->get();
        //$scores = RatingSubitem::pluck(DB::raw('0'), 'id')->all();
        $scores = [];
        return view('dormRatingMains.create', compact('periods', 'buildings', 'ratingCategories', 'scores'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  DormRatingMainCreateRequest $request
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function store(DormRatingMainCreateRequest $request)
    {
        try {
            $this->validator->with($request->all())->passesOrFail(ValidatorInterface::RULE_CREATE);
            $dormRatingMains = $this->repository->findWhere($request->only(['period_id', 'dorm_id']));
            DB::beginTransaction();
            if ($dormRatingMains->count() > 0) {
                $dormRatingMain = $dormRatingMains->first();
                $this->repository->update($request->all(), $dormRatingMain->id);
            } else {
                $dormRatingMain = $this->repository->create($request->all());
            }
            if ($request->has('dormRatings')) {
                //比较检查粗暴的删除，然后添加
                // $dormRatingMain->dormRatings()->delete();
                // $dormRatingMain->dormRatings()->createMany($request->get('dormRatings'));
                $dormRatings = $request->get('dormRatings');
                foreach ($dormRatings as $dormRating) {
                    $rating = DormitoryRating::updateOrCreate([
                        'dorm_id' => $dormRating['dorm_id'],
                        'period_id' => $dormRating['period_id'],
                        'subitem_id' => $dormRating['subitem_id']
                    ], $dormRating);
                    if ($rating) {
                        $rating->dormRatingMain()->associate($dormRatingMain);
                        $rating->save();
                    }
                }
            }
            DB::commit();

            $response = [
                'message' => 'DormRatingRemark created.',
                'data'    => $dormRatingMain->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {
            DB::rollBack();
            if ($request->wantsJson()) {
                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $dormRatingMain = $this->repository->find($id);

        if (request()->wantsJson()) {

            return response()->json([
                'data' => $dormRatingMain,
            ]);
        }

        return view('dormRatingMains.show', compact('dormRatingMain'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $periods = Period::orderBy('name', 'desc')->limit(24)->pluck('name', 'id');
        $buildings = Building::orderBy('name', 'asc')->pluck('name', 'id');
        $ratingCategories = RatingCategory::with('ratingSubitems')->get();
        $rating = $this->repository->with(['dorm', 'dormRatings'])->find($id);
        $scores = $rating->dormRatings->pluck('score', 'subitem_id');

        return view('dormRatingMains.create', compact('rating', 'periods', 'buildings', 'ratingCategories', 'scores'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  DormRatingMainUpdateRequest $request
     * @param  string            $id
     *
     * @return Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function update(DormRatingMainUpdateRequest $request, $id)
    {
        try {

            $this->validator->with($request->all())->passesOrFail(ValidatorInterface::RULE_UPDATE);

            DB::beginTransaction();

            $dormRatingMain = $this->repository->update($request->all(), $id);

            if ($request->has('dormRatings')) {
                $dormRatings = $request->get('dormRatings');
                foreach ($dormRatings as $dormRating) {
                    $rating = DormitoryRating::updateOrCreate([
                        'dorm_id' => $dormRating['dorm_id'],
                        'period_id' => $dormRating['period_id'],
                        'subitem_id' => $dormRating['subitem_id']
                    ], $dormRating);
                    if ($rating) {
                        $rating->dormRatingMain()->associate($dormRatingMain);
                        $rating->save();
                    }
                }
            }

            DB::commit();

            $response = [
                'message' => 'DormRatingMain updated.',
                'data'    => $dormRatingMain->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {
            DB::rollBack();
            if ($request->wantsJson()) {

                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $deleted = $this->repository->delete($id);

        if (request()->wantsJson()) {

            return response()->json([
                'message' => 'DormRatingMain deleted.',
                'deleted' => $deleted,
            ]);
        }

        return redirect()->back()->with('message', 'DormRatingMain deleted.');
    }
    public function export($perid_id)
    {
        return Excel::download(new DormitoryScoreExport($perid_id), '宿舍安全卫生评分表.xlsx');
    }
}
